export default class TxhTrack {
  constructor({ trackingList, sendColInfo, router, ClassmateNative, isInTxhApp }) {
    this.pageEnterTime = new Date()
    this.trackingList = trackingList
    this.sendColInfo = sendColInfo
    this.router = router
    this.ClassmateNative = ClassmateNative
    this.isInTxhApp = isInTxhApp
    if (this.checkData()) {
      // 处理遗留的埋点
      this.handleLocalData()
      this._init()
    }
  }

  // 检查传入的参数，参数有问题就不init
  checkData() {
    const { trackingList, sendColInfo, router, ClassmateNative } = this
    if (typeof trackingList !== 'object') return false
    if (typeof sendColInfo !== 'function') return false
    if (typeof router !== 'object') return false
    if (typeof ClassmateNative !== 'object') return false
    return true
  }

  // 处理遗留的埋点
  handleLocalData() {
    const data = JSON.parse(window.localStorage.getItem('txhLocalTrack'))
    if (data) {
      // 这里对时间做个处理
      data.pageEnterTime = new Date(data.pageEnterTime)
      data.pageExitTime = new Date(data.pageExitTime)
      data.pageDuration = data.pageExitTime.getTime() - data.pageEnterTime.getTime()
      this.sendColInfo(data)
      window.localStorage.removeItem('txhLocalTrack')
    }
  }
  _init() {
    // 先处理曝光埋点
    this.handleBeforeEach()
    // 再处理停留时长埋点
    this.handleAfterEach()
    // 最后处理页面被覆盖之后的曝光和提留时长埋点
    if (window && window.document) {
      this.handleDocumentHidden()
    }
  }

  // 通过路由守卫处理曝光埋点。区分端内端外
  handleBeforeEach() {
    const { router } = this
    if (router && typeof router.beforeEach === 'function') {
      router.beforeEach((to, from, next) => {
        this.nowPage = to.path
        this.handleBeforeEachMethod(to.path)
        next()
      })
    }
  }

  handleBeforeEachMethod(path) {
    const { isInTxhApp, sendColInfo, ClassmateNative } = this
    if (!isInTxhApp) {
      const timeObj = { pageEnterTime: new Date(), pageExitTime: new Date() }
      // 以每个path路径作为唯一key，比如首页就是/home
      if (this.trackingList[path]) {
        sendColInfo({ ...timeObj, ...this.trackingList[path] })
      }
    } else {
      const timeObj = { pageEnterTime: new Date(), pageExitTime: new Date() }
      // 以每个path路径作为唯一key，比如首页就是/home
      if (this.trackingList[path]) {
        // 如果在app内就从native方法中获取相应的埋点所需数据
        ClassmateNative && ClassmateNative.transferData({
          infoType: 'getEventInfo'
        }, (res) => {
          if (res) {
            const data = JSON.parse(res)
            const sendData = { ...data, ...timeObj, ...this.trackingList[path] }
            sendColInfo(sendData)
          } else {
            sendColInfo(this.trackingList[path])
          }
        })
      }
    }
  }

  // 处理停留时长埋点
  handleAfterEach() {
    const { router } = this
    if (router && typeof router.afterEach === 'function') {
      router.afterEach((to, from) => {
        this.handleAfterEachMethod(from.path)
      })
    }
  }

  handleAfterEachMethod(path) {
    const { isInTxhApp, sendColInfo, ClassmateNative } = this
    if (!isInTxhApp) {
      const timeObj = {
        pageEnterTime: this.pageEnterTime,
        pageExitTime: new Date(),
        pageDuration: new Date().getTime() - this.pageEnterTime.getTime()
      }
      // 以每个path路径作为唯一key，比如首页就是/home
      if (this.trackingList[path]) {
        sendColInfo({ ...timeObj, ...this.trackingList[path] })
      }
    } else {
      // 以每个path路径作为唯一key，比如首页就是/home
      if (this.trackingList[path]) {
        const timeObj = {
          pageEnterTime: this.pageEnterTime,
          pageExitTime: new Date(),
          pageDuration: new Date().getTime() - this.pageEnterTime.getTime()
        }
        // 如果在app内就从native方法中获取相应的埋点所需数据
        ClassmateNative && ClassmateNative.transferData({
          infoType: 'getEventInfo'
        }, (res) => {
          if (res) {
            const data = JSON.parse(res)
            sendColInfo({ ...data, ...timeObj, ...this.trackingList[path] })
          } else {
            sendColInfo({ ...timeObj, ...this.trackingList[path] })
          }
        })
      }
    }
    this.pageEnterTime = new Date()
  }

  // 处理页面切换埋点
  handleDocumentHidden() {
    const method = () => { this.visibilitychange() }
    window.document.addEventListener('visibilitychange', method)
    // 在页面移除的时候取消监听，否则可能触发多次事件
    window.onbeforeunload = () => {
      // 如果有对应页面埋点，那么就缓存在本地，等下次再次加载的时候再将此埋点埋上
      if (this.trackingList[this.nowPage]) {
        const obj = this.trackingList[this.nowPage]
        // 将进入和离开时间存入
        obj.pageEnterTime = this.pageEnterTime
        obj.pageExitTime = new Date()
        window.localStorage.setItem('txhLocalTrack', JSON.stringify(obj))
      }
      window.document.removeEventListener('visibilitychange', method)
    }
  }

  // 处理页面切换埋点的埋点方法
  visibilitychange() {
    // true代表页面隐藏，那么执行停留时长埋点
    if (document.hidden) {
      this.handleAfterEachMethod(this.nowPage)
    } else {
    // 执行曝光埋点
      this.handleBeforeEachMethod(this.nowPage)
    }
  }

  trackEvent(key, extraParams) {
    const { trackingList, sendColInfo } = this
    if (trackingList[key]) {
      if (extraParams && typeof extraParams === 'object') {
        sendColInfo({ ...trackingList[key], ...extraParams })
      } else {
        sendColInfo(trackingList[key])
      }
    }
  }
}

